package com.rendevous.main;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

import org.json.simple.parser.ParseException;

import com.rendevous.bean.Task;
import com.rendevous.service.ToDoList;
import com.rendevous.service.ToDoListImpl;
import com.rendevous.utils.CommandParser;
import com.rendevous.utils.Constants;

/**
 * @author How Wei Keng A0087836
 * @version 0.1
 * @since 15-10-2012
 * 
 *        This class is the service logic controller. Receives the user's input
 *        from Main, parsed, execute the parsed command and set the system's
 *        feedback message.
 * 
 *        Assumptions :
 * 
 */
public class ServiceController {
	private String systemFeedback;
	private boolean exitSystemStatus;

	/**
	 * 
	 * Parse and Execute the Parsed Command
	 * 
	 * @param userInput
	 *            -The user's command received from main
	 * @throws ParseException 
	 * @throws IOException 
	 * @see CommandParser#parseUserInput(String)
	 * @see CommandParser#getIsParsedStatus()
	 * @see CommandParser#parser.getParsedCommand()
	 * @see CommandParser#parser.getParsedArgs()
	 * @see CommandParser#getParserFeedback()
	 */
	public void execute(String userInput) throws IOException, ParseException {
		CommandParser parser = new CommandParser();
		boolean isParsed = true;
		String command = "";
		HashMap<String, Object> args = new HashMap<String, Object>();
		parser.parseUserInput(userInput);
		isParsed = parser.getIsParsedStatus();
		if (isParsed) {
			command = parser.getParsedCommand();
			args = parser.getParsedArgs();
			executeCommandService(command, args);
		} else {
			this.systemFeedback = parser.getParserFeedback();
		}
	}

	/**
	 * 
	 * Execute the service for the user's command
	 * @throws ParseException 
	 * @throws IOException 
	 */
	private void executeCommandService(String command,
			HashMap<String, Object> args) throws IOException, ParseException {
		ToDoList service = new ToDoListImpl();
		switch (command) {
		case Constants.CMD_ADD:
			executeAddService(service, args);
			break;
		case Constants.CMD_UPDATE:
			executeUpdateService(service, args);
			break;
		case Constants.CMD_SEARCH:
			executeSearchService(service, args);
			break;
		case Constants.CMD_DO:
			executeDoService(service, args);
			break;
		case Constants.CMD_REMOVE:
			executeRemoveService(service, args);
			break;
		case Constants.CMD_LIST:
			executeListService(service, args);
			break;
		case Constants.CMD_LIST_BY_DATE:
			executelssService(service, args);
			break;
		case Constants.CMD_LIST_BY_PRIORITY:
			executelspService(service, args);
			break;
		case Constants.CMD_SWITCH:
			executeSwitchService(service, args);
			break;
		case Constants.CMD_UNDO:
			executeUndoService(service, args);
			break;
		case Constants.CMD_HELP:
			executeHelpService(service, args);
			break;
		case Constants.CMD_EXIT:
			executeExitService();
			break;
		default:
			break;
		}
	}

	private void executelspService(ToDoList service,
			HashMap<String, Object> args) {
	}

	private void executelssService(ToDoList service,
			HashMap<String, Object> args) {
	}

	private void executeHelpService(ToDoList service,
			HashMap<String, Object> args) {
		this.systemFeedback = service.help();
	}

	private void executeUndoService(ToDoList service,
			HashMap<String, Object> args) {
		this.systemFeedback = service.undo();
	}

	private void executeSwitchService(ToDoList service,
			HashMap<String, Object> args) throws IOException, ParseException {
		this.systemFeedback = service.switchDataFile();
	}

	private void executeListService(ToDoList service,
			HashMap<String, Object> args) {
	}

	private void executeRemoveService(ToDoList service,
			HashMap<String, Object> args) {
		int taskNum = (Integer) args.get("taskNum");
		this.systemFeedback = service.deleteTask(taskNum);
	}

	private void executeDoService(ToDoList service, HashMap<String, Object> args) throws IOException, ParseException {
		long taskNum = (Long) args.get("taskNum");
		this.systemFeedback = service.completeTask(taskNum);
	}

	private void executeSearchService(ToDoList service,
			HashMap<String, Object> args) {
		// service.searchByCondition();
	}

	private void executeUpdateService(ToDoList service,
			HashMap<String, Object> args) {
		String content = (String) args.get("content");
		List<String> tagsList = new ArrayList<String>();
		tagsList = (List<String>) args.get("tagsList");
		Date startDate = (Date) args.get("startDate");
		// Date endDate = (Date) args.get("endDate");
		// String priority = (String) args.get("priority");
		int taskNum = (Integer) args.get("taskNum");
		Task newTask = new Task();
		newTask.setContent(content);
		newTask.setStartTime(startDate);
		newTask.setTagList(tagsList);
		service.updateTask(taskNum, newTask);
		this.systemFeedback = Constants.MSG_UPDATED;
	}

	private void executeAddService(ToDoList service,
			HashMap<String, Object> args) {
		String content = (String) args.get("content");
		List<String> tagsList = new ArrayList<String>();
		tagsList = (List<String>) args.get("tagsList");
		Date startDate = (Date) args.get("startDate");
		// Date endDate = (Date) args.get("endDate");
		// String priority = (String) args.get("priority");
		Task newTask = new Task();
		newTask.setContent(content);
		newTask.setStartTime(startDate);
		newTask.setTagList(tagsList);
		service.addTask(newTask);
		this.systemFeedback = Constants.MSG_ADDED;
	}

	private void executeExitService() {
		this.systemFeedback = Constants.MSG_EXIT;
		this.exitSystemStatus = true;
	}

	public String getSystemFeedback() {
		return this.systemFeedback;
	}

	public boolean getExitSystemStatus() {
		return this.exitSystemStatus;
	}
}